package com.aliyun.dingtalk.service.impl;

import com.aliyun.dingtalk.service.AttendanceCacheService;
import com.aliyun.dingtalk.service.DingTalkUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.*;
import java.text.SimpleDateFormat;
import java.util.concurrent.TimeUnit;

@Service
public class AttendanceCacheServiceImpl implements AttendanceCacheService {

    @Autowired
    private DingTalkUserService dingTalkUserService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    private static final String ATTENDANCE_CACHE_KEY = "attendance:current_month";

    /**
     * 每10分钟执行一次定时任务，更新考勤数据缓存
     */
    @Scheduled(fixedRate = 600000) // 600000毫秒 = 10分钟
    @Override
    public void cacheAttendanceData() {
        try {
            // 获取所有用户信息
            Object allUsersData = dingTalkUserService.getAllUsersWithDetails();

            if (allUsersData instanceof Map) {
                Map<String, Object> userDataMap = (Map<String, Object>) allUsersData;
                Object userListWithDetailsObj = userDataMap.get("userListWithDetails");

                if (userListWithDetailsObj instanceof List) {
                    List<Map<String, Object>> userListWithDetails = (List<Map<String, Object>>) userListWithDetailsObj;

                    // 提取所有用户ID
                    List<String> userIdList = new ArrayList<>();
                    for (Map<String, Object> userWithDetails : userListWithDetails) {
                        Object userId = userWithDetails.get("userId");
                        if (userId != null) {
                            userIdList.add(userId.toString());
                        }
                    }

                    // 获取最近三个月的数据
                    Map<String, List<Object>> threeMonthsData = new HashMap<>();
                    for (int i = 0; i < 3; i++) {
                        String[] dateRange = getMonthRange(i);  // 0表示当前月，1表示上月，2表示上上月
                        String startDate = dateRange[0];
                        String endDate = dateRange[1];

                        List<Object> monthData = getAttendanceListWithPagination(
                                userIdList, startDate, endDate);

                        threeMonthsData.put(getMonthKey(i), monthData);
                    }

                    // 将结果存储到Redis，设置过期时间24小时
                    redisTemplate.opsForValue().set(ATTENDANCE_CACHE_KEY, threeMonthsData, 24, TimeUnit.HOURS);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 使用分段查询逻辑获取考勤数据
     */
    private List<Object> getAttendanceListWithPagination(List<String> userIdList,
                                                         String startDate,
                                                         String endDate) throws Exception {
        // 设置默认值
        long defaultLimit = 50L;
        long defaultOffset = 0L;

        // 检查时间跨度是否超过7天，如果超过则分段查询
        List<Object> allResults = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdfWithTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        Date start = sdf.parse(startDate);
        Date end = sdf.parse(endDate);

        // 设置开始时间为当天 00:00:00
        Calendar startCal = Calendar.getInstance();
        startCal.setTime(start);
        startCal.set(Calendar.HOUR_OF_DAY, 0);
        startCal.set(Calendar.MINUTE, 0);
        startCal.set(Calendar.SECOND, 0);
        startCal.set(Calendar.MILLISECOND, 0);
        Date startTime = startCal.getTime();

        // 设置结束时间为当天 23:59:59
        Calendar endCal = Calendar.getInstance();
        endCal.setTime(end);
        endCal.set(Calendar.HOUR_OF_DAY, 23);
        endCal.set(Calendar.MINUTE, 59);
        endCal.set(Calendar.SECOND, 59);
        endCal.set(Calendar.MILLISECOND, 999);
        Date endTime = endCal.getTime();

        long diffInDays = (endTime.getTime() - startTime.getTime()) / (1000 * 60 * 60 * 24);

        if (diffInDays > 7 || userIdList.size() > 1) {
            // 如果时间跨度超过7天或者查询多个用户，需要分段查询
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startTime);

            Date currentStart = startTime;
            while (currentStart.before(endTime) || currentStart.equals(endTime)) {
                calendar.setTime(currentStart);
                calendar.add(Calendar.DAY_OF_MONTH, 6); // 加6天，总共7天

                Date currentEnd = calendar.getTime();
                if (currentEnd.after(endTime)) {
                    currentEnd = endTime;
                }

                // 如果是多个用户，为每个用户单独查询
                if (userIdList.size() > 1) {
                    for (String userId : userIdList) {
                        List<String> singleUserList = Arrays.asList(userId);
                        Object result = dingTalkUserService.getAttendanceList(
                                singleUserList,
                                sdfWithTime.format(currentStart),
                                sdfWithTime.format(currentEnd),
                                defaultOffset,
                                defaultLimit
                        );

                        // 合并结果
                        if (result instanceof List) {
                            allResults.addAll((List<?>) result);
                        }
                    }
                } else {
                    // 单个用户查询
                    Object result = dingTalkUserService.getAttendanceList(
                            userIdList,
                            sdfWithTime.format(currentStart),
                            sdfWithTime.format(currentEnd),
                            defaultOffset,
                            defaultLimit
                    );

                    // 合并结果
                    if (result instanceof List) {
                        allResults.addAll((List<?>) result);
                    }
                }

                // 下一次查询从当前结束日期的第二天开始
                calendar.setTime(currentEnd);
                calendar.add(Calendar.DAY_OF_MONTH, 1);
                currentStart = calendar.getTime();
            }

            // 对合并后的结果按日期排序
            allResults.sort((r1, r2) -> {
                if (r1 instanceof Map && r2 instanceof Map) {
                    Map<String, Object> map1 = (Map<String, Object>) r1;
                    Map<String, Object> map2 = (Map<String, Object>) r2;
                    String date1 = (String) map1.get("date");
                    String date2 = (String) map2.get("date");
                    return date1 != null && date2 != null ? date1.compareTo(date2) : 0;
                }
                return 0;
            });

        } else {
            // 时间跨度不超过7天且单个用户，直接查询
            Object result = dingTalkUserService.getAttendanceList(
                    userIdList,
                    sdfWithTime.format(startTime),
                    sdfWithTime.format(endTime),
                    defaultOffset,
                    defaultLimit
            );

            if (result instanceof List) {
                allResults.addAll((List<?>) result);
            }
        }

        return allResults;
    }



    /**
     * 获取缓存的考勤数据（可按时间范围筛选）
     */
    @Override
    public Object getCachedAttendanceData(String startDate, String endDate) {
        Object cachedData = redisTemplate.opsForValue().get(ATTENDANCE_CACHE_KEY);

        // 如果没有传入时间范围，则返回全部数据
        if (startDate == null || endDate == null) {
            return cachedData;
        }

        // 解析输入的时间范围
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date start, end;
        try {
            start = sdf.parse(startDate);
            end = sdf.parse(endDate);
        } catch (Exception e) {
            throw new RuntimeException("日期格式错误: " + e.getMessage());
        }

        // 处理不同数据结构的缓存数据
        if (cachedData instanceof Map) {
            // 三个月数据的情况
            return filterAttendanceDataFromMap((Map<String, List<Object>>) cachedData, start, end, sdf);
        } else if (cachedData instanceof List) {
            // 单月数据的情况
            return filterAttendanceDataFromList((List<Object>) cachedData, start, end, sdf);
        }

        return cachedData;
    }

    /**
     * 从Map结构（三个月数据）中筛选考勤数据
     */
    private List<Object> filterAttendanceDataFromMap(Map<String, List<Object>> threeMonthsData,
                                                     Date start, Date end, SimpleDateFormat sdf) {
        List<Object> filteredData = new ArrayList<>();

        try {
            // 遍历三个月的数据，筛选符合条件的记录
            for (List<Object> monthData : threeMonthsData.values()) {
                for (Object record : monthData) {
                    if (record instanceof Map) {
                        Map<String, Object> recordMap = (Map<String, Object>) record;
                        String recordDateStr = (String) recordMap.get("date");

                        if (recordDateStr != null) {
                            Date recordDate = sdf.parse(recordDateStr);
                            if (!recordDate.before(start) && !recordDate.after(end)) {
                                filteredData.add(record);
                            }
                        }
                    }
                }
            }

            // 按日期排序
            sortAttendanceData(filteredData);
            return filteredData;
        } catch (Exception e) {
            throw new RuntimeException("时间筛选失败: " + e.getMessage());
        }
    }

    /**
     * 从List结构（单月数据）中筛选考勤数据
     */
    private List<Object> filterAttendanceDataFromList(List<Object> monthData,
                                                      Date start, Date end, SimpleDateFormat sdf) {
        List<Object> filteredData = new ArrayList<>();

        try {
            for (Object record : monthData) {
                if (record instanceof Map) {
                    Map<String, Object> recordMap = (Map<String, Object>) record;
                    String recordDateStr = (String) recordMap.get("date");

                    if (recordDateStr != null) {
                        Date recordDate = sdf.parse(recordDateStr);
                        if (!recordDate.before(start) && !recordDate.after(end)) {
                            filteredData.add(record);
                        }
                    }
                }
            }

            // 按日期排序
            sortAttendanceData(filteredData);
            return filteredData;
        } catch (Exception e) {
            throw new RuntimeException("时间筛选失败: " + e.getMessage());
        }
    }

    /**
     * 对考勤数据按日期排序
     */
    private void sortAttendanceData(List<Object> data) {
        data.sort((r1, r2) -> {
            if (r1 instanceof Map && r2 instanceof Map) {
                Map<String, Object> map1 = (Map<String, Object>) r1;
                Map<String, Object> map2 = (Map<String, Object>) r2;
                String date1 = (String) map1.get("date");
                String date2 = (String) map2.get("date");
                return date1 != null && date2 != null ? date1.compareTo(date2) : 0;
            }
            return 0;
        });
    }


    /**
     * 获取当前月的第一天和最后一天
     */
    private String[] getCurrentMonthRange() {
        Calendar calendar = Calendar.getInstance();

        // 设置为当前月的第一天
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String startDate = sdf.format(calendar.getTime());

        // 设置为当前月的最后一天
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        String endDate = sdf.format(calendar.getTime());

        return new String[]{startDate, endDate};
    }


    public void manualCacheAttendanceData() {
        try {
            // 获取所有用户信息
            Object allUsersData = dingTalkUserService.getAllUsersWithDetails();

            if (allUsersData instanceof Map) {
                Map<String, Object> userDataMap = (Map<String, Object>) allUsersData;
                Object userListWithDetailsObj = userDataMap.get("userListWithDetails");

                if (userListWithDetailsObj instanceof List) {
                    List<Map<String, Object>> userListWithDetails = (List<Map<String, Object>>) userListWithDetailsObj;

                    // 提取所有用户ID
                    List<String> userIdList = new ArrayList<>();
                    for (Map<String, Object> userWithDetails : userListWithDetails) {
                        Object userId = userWithDetails.get("userId");
                        if (userId != null) {
                            userIdList.add(userId.toString());
                        }
                    }

                    // 获取最近三个月的数据
                    Map<String, List<Object>> threeMonthsData = new HashMap<>();
                    for (int i = 0; i < 3; i++) {
                        String[] dateRange = getMonthRange(i);  // 0表示当前月，1表示上月，2表示上上月
                        String startDate = dateRange[0];
                        String endDate = dateRange[1];

                        List<Object> monthData = getAttendanceListWithPagination(
                                userIdList, startDate, endDate);

                        threeMonthsData.put(getMonthKey(i), monthData);
                    }

                    // 将结果存储到Redis，设置过期时间24小时
                    redisTemplate.opsForValue().set(ATTENDANCE_CACHE_KEY, threeMonthsData, 24, TimeUnit.HOURS);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("手动缓存考勤数据失败: " + e.getMessage());
        }
    }

    /**
     * 获取指定月份的日期范围（0=当前月，1=上月，2=上上月）
     */
    private String[] getMonthRange(int monthsAgo) {
        Calendar calendar = Calendar.getInstance();

        // 调整月份
        calendar.add(Calendar.MONTH, -monthsAgo);

        // 设置为该月的第一天
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String startDate = sdf.format(calendar.getTime());

        // 设置为该月的最后一天
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        String endDate = sdf.format(calendar.getTime());

        return new String[]{startDate, endDate};
    }

    /**
     * 生成月份标识符
     */
    private String getMonthKey(int monthsAgo) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -monthsAgo);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        return sdf.format(calendar.getTime());
    }
}
